package org.zhangchao.poi.excel.process;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.ss.usermodel.Row;
import org.zhangchao.poi.excel.common.ExcelEnum;

/**
 * Excel 解析器，兼容Excel-2003与Excel-2007
 * 
 * @author zhangchao
 * 
 */
public abstract class ExcelProcessor implements ExcelProcessable {
	
	private ExcelProcessable processor;

	/**
	 * 根据文件全名构建解析器
	 * @param fileName
	 * @throws Exception
	 */
	public ExcelProcessor(String fileName) throws Exception {
		if (fileName == null || fileName.equals("")) {
			throw new Exception("构造Excel解析器失败，未指定文件全名。");
		}
		File file = new File(fileName);
		if (!file.exists()) {
			throw new Exception("构造Excel解析器失败，指定的文件不存在：" + fileName);
		}
		if (fileName.endsWith("xls")) {
			processor = new MyExcel2003Processor(fileName);
		} else {
			processor = new MyExcel2007Processor(fileName);
		}
	}
	
	/**
	 * 根据文件构建解析器
	 * @param file
	 * @throws Exception
	 */
	public ExcelProcessor(File file) throws Exception {
		if(null == file) {
			throw new Exception("构造Excel解析器失败：传入的file == null！");
		}
		ExcelEnum type = null;
		String fileName = file.getName().toUpperCase();
		if(fileName.endsWith(".XLS")) {
			type = ExcelEnum.TYPE2003;
		}else if(fileName.endsWith(".XLSX")) {
			type = ExcelEnum.TYPE2007;
		}
		if(ExcelEnum.TYPE2003.equals(type)) {
			processor = new MyExcel2003Processor(file);
		}else if(ExcelEnum.TYPE2007.equals(type)) {
			processor = new MyExcel2007Processor(file);
		}else {
			throw new Exception("构造Excel解析器失败：传入的类型不对！");
		}
	}
	
	/**
	 * 根据文件构建解析器
	 * @param file
	 * @param type 
	 * @throws Exception
	 */
	public ExcelProcessor(File file, ExcelEnum type) throws Exception {
		if(ExcelEnum.TYPE2003.equals(type)) {
			processor = new MyExcel2003Processor(file);
		}else if(ExcelEnum.TYPE2007.equals(type)) {
			processor = new MyExcel2007Processor(file);
		}else {
			throw new Exception("构造Excel解析器失败：传入的类型不对！");
		}
	}
	
	/**
	 * 根据输入流构建解析器
	 * @param is
	 * @param type 
	 * @throws Exception
	 */
	public ExcelProcessor(InputStream is, ExcelEnum type) throws Exception {
		if(ExcelEnum.TYPE2003.equals(type)) {
			processor = new MyExcel2003Processor(is);
		}else if(ExcelEnum.TYPE2007.equals(type)) {
			processor = new MyExcel2007Processor(is);
		}else {
			throw new Exception("构造Excel解析器失败：传入的类型不对！");
		}
	}

	/**
	 * 解析一个指定索引的sheet
	 * @param sheetIndex sheet 索引（从1开始）
	 * @throws Exception
	 */
	//@Override
	public void processOneSheet(int sheetIndex) throws Exception {
		processor.processOneSheet(sheetIndex);
	}
	
	/**
	 * 解析所有sheet
	 * @throws Exception
	 */
	//@Override
	public void processAllSheets() throws Exception {
		processor.processAllSheets();
	}

	/**
	 * 停止解析
	 * @throws IOException
	 */
	//@Override
	public void stop() throws IOException {
		processor.stop();
	}

	/**
	 * 解析处理行数据的策略
	 * @param row
	 * @param sheet
	 */
	//@Override
	public abstract void processRow(Row row);

	private class MyExcel2003Processor extends Excel2003Processor {
		public MyExcel2003Processor(String filename) throws Exception {
			super(filename);
		}
		
		public MyExcel2003Processor(File file) throws Exception {
			super(file);
		}
		
		public MyExcel2003Processor(InputStream is) throws Exception {
			super(is);
		}

		@Override
		public void processRow(Row row) {
			ExcelProcessor.this.processRow(row);
		}
	}

	private class MyExcel2007Processor extends Excel2007Processor {
		public MyExcel2007Processor(String filename) throws Exception {
			super(filename);
		}
		
		public MyExcel2007Processor(File file) throws Exception {
			super(file);
		}
		
		public MyExcel2007Processor(InputStream is) throws Exception {
			super(is);
		}

		@Override
		public void processRow(Row row) {
			ExcelProcessor.this.processRow(row);
		}

	}
	
}
